/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.bookingmanager.web;

import cz.muni.fi.pa165.bookingmanager.adapters.HotelAdapter;
import cz.muni.fi.pa165.bookingmanager.adapters.ReservationAdapter;
import cz.muni.fi.pa165.bookingmanager.adapters.RoomAdapter;
import cz.muni.fi.pa165.bookingmanager.dto.HotelDTO;
import cz.muni.fi.pa165.bookingmanager.dto.ReservationDTO;
import cz.muni.fi.pa165.bookingmanager.dto.RoomDTO;
import cz.muni.fi.pa165.bookingmanager.exceptions.IllegalOrphanException;
import cz.muni.fi.pa165.bookingmanager.exceptions.NonexistentEntityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Radek Koubsky
 */
@UrlBinding("/admin/hotel/{$event}")
public class HotelActionBean extends MyActionBean {

    final static Logger log = LoggerFactory.getLogger(HotelActionBean.class);
    private HotelAdapter hotelAdapter;
    private ReservationAdapter reservationAdapter;
    private RoomAdapter roomAdapter;
    private List<HotelDTO> list = new ArrayList<HotelDTO>();
    @ValidateNestedProperties(value = {
        @Validate(on = {"add", "save"}, field = "name", required = true),
        @Validate(on = {"add", "save"}, field = "adress", required = true),
        @Validate(on = {"add", "save"}, field = "description", required = true),
        @Validate(on = {"add", "save"}, field = "city", required = true)
    })
    private HotelDTO hotel;
    private String hotelName;
    private String hotelCity;

    public HotelActionBean() throws NamingException {
        Context ctx = new InitialContext();
        hotelAdapter = (HotelAdapter) ctx.lookup("java:global/cz.muni.fi.pa165.bookingmanager_booking_manager-web_war_1.0-SNAPSHOT/HotelAdapterImpl!cz.muni.fi.pa165.bookingmanager.adapters.HotelAdapter");
        this.reservationAdapter = (ReservationAdapter) ctx.lookup("java:global/cz.muni.fi.pa165.bookingmanager_booking_manager-web_war_1.0-SNAPSHOT/ReservationAdapterImpl!cz.muni.fi.pa165.bookingmanager.adapters.ReservationAdapter");
        this.roomAdapter = (RoomAdapter) ctx.lookup("java:global/cz.muni.fi.pa165.bookingmanager_booking_manager-web_war_1.0-SNAPSHOT/RoomAdapterImpl!cz.muni.fi.pa165.bookingmanager.adapters.RoomAdapter");
        list = getHotels();
    }

    @DefaultHandler
    public Resolution all() {
        log.debug("all()");

        return new ForwardResolution("/backend/hotels/list.jsp");
    }

    public HotelDTO getHotel() {
        return hotel;
    }

    public void setHotel(HotelDTO hotel) {
        this.hotel = hotel;
        getContext().setHotel(hotel);
    }    

    public Resolution add() throws IllegalOrphanException {
        log.debug("add() hotel={}", hotel);
        List<RoomDTO> rooms = new ArrayList<RoomDTO>();
        hotel.setRooms(rooms);
        hotelAdapter.createHotel(hotel);
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution delete() throws NonexistentEntityException, IllegalOrphanException {
        log.debug("delete({})", hotel);
        
        hotelAdapter.deleteHotel(hotel);
        return new RedirectResolution(this.getClass(), "all");
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"delete", "edit", "save", "getRooms", "getReservations", "getBooking", "frontendHotelDetail"})
    public void loadHotelFromDatabase() {
        String ids = getContext().getRequest().getParameter("hotel.id");

        if (ids == null) {
            return;
        }
        this.setHotel(hotelAdapter.getHotelById(Long.parseLong(ids)));        
    }

    public Resolution edit() {
        log.debug("edit() hotel={}", hotel);
        return new ForwardResolution("/backend/hotels/edit.jsp");
    }

    public Resolution getRooms() {
        log.debug("getRooms() hotel={}", hotel);
        return new RedirectResolution(RoomActionBean.class, "all");
    }

    public Resolution getReservations() {
        log.debug("getReservations() hotel={}", hotel);
        return new RedirectResolution(ReservationActionBean.class, "all");
    }

    public Resolution getBooking() {
        log.debug("getBooking() hotel={}", hotel);
        return new RedirectResolution(BookingActionBean.class, "all");
    }

    public Resolution save() throws NonexistentEntityException, IllegalOrphanException, Exception {
        log.debug("save() book={}", hotel);
        hotelAdapter.updateHotel(hotel);
        return new RedirectResolution(this.getClass(), "all");
    }

    public Resolution frontendHotelsList() {
        log.debug("frontendHotelsList");
        list = getHotels();
        return new ForwardResolution("/frontend/hotelsList.jsp");
    }

    public Resolution frontendHotelDetail() {
        log.debug("frontendHotelDetail");
        return new ForwardResolution("/frontend/hotelsDetail.jsp");
    }    

    public String getHotelName() {
        return hotelName;
    }

    public void setHotelName(String hotelName) {
        this.hotelName = hotelName;
    }

    public String getHotelCity() {
        return hotelCity;
    }

    public void setHotelCity(String hotelCity) {
        this.hotelCity = hotelCity;
    }

    public List<HotelDTO> getList() {
        if (this.list == null) {
            return null;
        }
        return Collections.unmodifiableList(list);
    }

    public void setList(List<HotelDTO> list) {
        this.list = new ArrayList<HotelDTO>();
        this.list.addAll(list);
    }

    public List<HotelDTO> getHotels() {
        return hotelAdapter.findAllHotels();
    }

    public Resolution findHotelsByNameOrCity() {
        if (hotelName == null && hotelCity == null) {
            return new RedirectResolution(this.getClass(), "all");
        } else if (hotelName != null && hotelCity == null) {
            list = hotelAdapter.findHotelsByName(hotelName);
        } else if (hotelName == null && hotelCity != null) {
            list = hotelAdapter.findHotelsByCity(hotelCity);
        } else if (hotelName != null && hotelCity != null) {
            list.clear();
            for (HotelDTO hotel1 : hotelAdapter.findAllHotels()) {
                if (hotel1.getName().equals(hotelName) && hotel1.getCity().equals(hotelCity)) {
                    list.add(hotel1);
                }
            }
        }
        return new ForwardResolution("/backend/hotels/list.jsp");
    }
}
